一个类第一次被用到的时候,才被动态加载到JVM。一个类完整的过程分为如下三步:
下面这个实验,为了看得清楚,已经按照实际执行的先后顺序排列:
/**
* 工具类。只是为了在成员字段赋值的时候,打印目前在执行哪一步
*/
class Log{
static String BaseFieldInit(){System.out.println("Base Normal Field");return "";}
static String BaseStaticFieldInit(){System.out.println("Base Static Field");return "";}
static String fieldInit(){System.out.println("Normal Field");return "";}
static String staticFieldInit(){System.out.println("Static Field");return "";}
}
/**
* 基类
*/
class Base {
/*1*/ static {System.out.println("Base Static Block 1");}
/*1*/ private static String staticValue=Log.BaseStaticFieldInit();
/*1*/ static {System.out.println("Base Static Block 2");}
/*3*/ {System.out.println("Base Normal Block 1");}
/*3*/ private String value=Log.BaseFieldInit();
/*3*/ {System.out.println("Base Normal Block 2");}
/*4*/ Base(){System.out.println("Base Constructor");}
}
/**
* 派生类
*/
public class TestInit extends Base{
/*2*/ static {System.out.println("Static Block 1");}
/*2*/ private static String staticValue=Log.staticFieldInit();
/*2*/ static {System.out.println("Static Block 2");}
/*5*/ {System.out.println("Normal Block 1");}
/*5*/ private String value=Log.fieldInit();
/*5*/ {System.out.println("Normal Block 2");}
/*6*/ TestInit(){System.out.println("Constructor");}
/**
* MAIN 主线程
*/
public static void main(String[] args){
TestInit ti=new TestInit();
}
}